﻿using SupportLayer.Constantes.Outros;
using SupportLayer.Enums;
using SupportLayer.Objetos.Espacamento;
using System;
using System.Collections.Generic;
using System.Linq;

namespace SupportLayer.Util
{
  public class Espacamento
  {
    public List<EspacamentoClass> GetEspacamentoLetras(string _mensagem, AlturaLetra _altura, string _fonte, out int Width)
    {
      double Razao = (double)_altura / 100;

      List<EspacamentoClass> lstEspacamento = new List<EspacamentoClass>();
      Width = 0;

      for (int x = 0; x < _mensagem.ToCharArray().Count(); x++)
      {
        char letra = _mensagem.ToCharArray()[x];
        EspacamentoClass esp = new EspacamentoClass();

        if (_fonte == FONTES.RoadGeekD)
          esp = Letra100D(letra);
        else if (_fonte == FONTES.RoadGeekEM)
          esp = Letra100EM(letra);
        else return null;

        Int16 direita = (x < _mensagem.ToCharArray().Count() - 1) ? Convert.ToInt16(Round(esp.Direita, Razao)) : (Int16)0;
        Int16 esquerda = (x > 0) ? Convert.ToInt16(Round(esp.Esquerda, Razao)) : (Int16)0;
        Int16 largura = Convert.ToInt16(Round(esp.Largura, Razao));

        if (x > 0)
          Width += esquerda;
        if (x < _mensagem.ToCharArray().Count() - 1)
          Width += direita;
        Width += largura;

        if (x > 0)
          if (_mensagem.ToCharArray()[x - 1] == ' ')
            Width -= esquerda;

        if (x < _mensagem.ToCharArray().Count() - 1)
          if (_mensagem.ToCharArray()[x + 1] == ' ')
            Width -= direita;

        lstEspacamento.Add(new EspacamentoClass()
        {
          Caractere = letra,
          Direita = direita,
          Esquerda = esquerda,
          Largura = largura
        });
      }
      return lstEspacamento;
    }

    public static int RoundGap(int _numero, int arredondamento)
    {
      int sobra = _numero % arredondamento;
      if (sobra < arredondamento / 2)
        return -sobra;
      else
        return arredondamento - sobra;
    }

    public static int Round(int _numero, double _razao)
    {
      double result = _numero % _razao;
      double answer = 0;

      if (result < 0.5)
      {
        answer = Math.Floor((double)_numero * _razao);
      }
      else
        answer = Math.Ceiling((double)_numero * _razao);

      return Convert.ToInt32(answer);
    }

    private EspacamentoClass Letra100EM(char Letra)
    {
      switch (Letra)
      {
        case 'A':
        case 'Á':
        case 'Ã':
        case 'Â':
        case 'À':
          return new EspacamentoClass() { Esquerda = 4, Largura = 101, Direita = 4 };

        case 'B':
          return new EspacamentoClass() { Esquerda = 14, Largura = 81, Direita = 8 };

        case 'C':
        case 'Ç':
          return new EspacamentoClass() { Esquerda = 10, Largura = 81, Direita = 8 };

        case 'D':
          return new EspacamentoClass() { Esquerda = 14, Largura = 81, Direita = 10 };

        case 'E':
        case 'É':
        case 'Ê':
        case 'È':
          return new EspacamentoClass() { Esquerda = 14, Largura = 74, Direita = 7 };

        case 'F':
          return new EspacamentoClass() { Esquerda = 14, Largura = 74, Direita = 7 };

        case 'G':
          return new EspacamentoClass() { Esquerda = 10, Largura = 81, Direita = 10 };

        case 'H':
          return new EspacamentoClass() { Esquerda = 14, Largura = 81, Direita = 14 };

        case 'I':
        case 'Í':
        case 'Ì':
        case 'Î':
          return new EspacamentoClass() { Esquerda = 14, Largura = 20, Direita = 14 };

        case 'J':
          return new EspacamentoClass() { Esquerda = 4, Largura = 76, Direita = 14 };

        case 'K':
          return new EspacamentoClass() { Esquerda = 14, Largura = 82, Direita = 2 };

        case 'L':
          return new EspacamentoClass() { Esquerda = 14, Largura = 74, Direita = 2 };

        case 'M':
          return new EspacamentoClass() { Esquerda = 14, Largura = 93, Direita = 14 };

        case 'N':
          return new EspacamentoClass() { Esquerda = 14, Largura = 81, Direita = 14 };

        case 'O':
        case 'Ó':
        case 'Ò':
        case 'Õ':
        case 'Ô':
          return new EspacamentoClass() { Esquerda = 10, Largura = 84, Direita = 10 };

        case 'P':
          return new EspacamentoClass() { Esquerda = 14, Largura = 81, Direita = 4 };

        case 'Q':
          return new EspacamentoClass() { Esquerda = 10, Largura = 84, Direita = 10 };

        case 'R':
          return new EspacamentoClass() { Esquerda = 14, Largura = 81, Direita = 7 };

        case 'S':
          return new EspacamentoClass() { Esquerda = 11, Largura = 81, Direita = 11 };

        case 'T':
          return new EspacamentoClass() { Esquerda = 4, Largura = 74, Direita = 4 };

        case 'U':
        case 'Ú':
        case 'Ù':
        case 'Û':
          return new EspacamentoClass() { Esquerda = 14, Largura = 81, Direita = 14 };

        case 'V':
          return new EspacamentoClass() { Esquerda = 4, Largura = 92, Direita = 4 };

        case 'W':
          return new EspacamentoClass() { Esquerda = 4, Largura = 106, Direita = 4 };

        case 'X':
          return new EspacamentoClass() { Esquerda = 8, Largura = 87, Direita = 7 };

        case 'Y':
          return new EspacamentoClass() { Esquerda = 4, Largura = 101, Direita = 4 };

        case 'Z':
          return new EspacamentoClass() { Esquerda = 8, Largura = 81, Direita = 7 };

        case 'a':
        case 'á':
        case 'ã':
        case 'â':
        case 'à':
          return new EspacamentoClass() { Esquerda = 11, Largura = 66, Direita = 20 };

        case 'b':
          return new EspacamentoClass() { Esquerda = 20, Largura = 66, Direita = 11 };

        case 'c':
        case 'ç':
          return new EspacamentoClass() { Esquerda = 11, Largura = 66, Direita = 11 };

        case 'd':
          return new EspacamentoClass() { Esquerda = 11, Largura = 66, Direita = 20 };

        case 'e':
        case 'é':
        case 'ê':
        case 'è':
          return new EspacamentoClass() { Esquerda = 11, Largura = 66, Direita = 11 };

        case 'f':
          return new EspacamentoClass() { Esquerda = 10, Largura = 42, Direita = 11 };

        case 'g':
          return new EspacamentoClass() { Esquerda = 11, Largura = 66, Direita = 20 };

        case 'h':
          return new EspacamentoClass() { Esquerda = 20, Largura = 66, Direita = 20 };

        case 'i':
        case 'í':
        case 'ì':
        case 'î':
          return new EspacamentoClass() { Esquerda = 20, Largura = 20, Direita = 20 };

        case 'j':
          return new EspacamentoClass() { Esquerda = 2, Largura = 37, Direita = 20 };

        case 'k':
          return new EspacamentoClass() { Esquerda = 20, Largura = 66, Direita = 11 };

        case 'l':
          return new EspacamentoClass() { Esquerda = 20, Largura = 20, Direita = 20 };

        case 'm':
          return new EspacamentoClass() { Esquerda = 20, Largura = 110, Direita = 20 };

        case 'n':
          return new EspacamentoClass() { Esquerda = 20, Largura = 66, Direita = 20 };

        case 'o':
        case 'ó':
        case 'ò':
        case 'õ':
        case 'ô':
          return new EspacamentoClass() { Esquerda = 11, Largura = 68, Direita = 11 };

        case 'p':
          return new EspacamentoClass() { Esquerda = 20, Largura = 66, Direita = 11 };

        case 'q':
          return new EspacamentoClass() { Esquerda = 11, Largura = 66, Direita = 20 };

        case 'r':
          return new EspacamentoClass() { Esquerda = 20, Largura = 50, Direita = 4 };

        case 's':
          return new EspacamentoClass() { Esquerda = 10, Largura = 66, Direita = 11 };

        case 't':
          return new EspacamentoClass() { Esquerda = 9, Largura = 52, Direita = 12 };

        case 'u':
        case 'ú':
        case 'ù':
        case 'û':
          return new EspacamentoClass() { Esquerda = 20, Largura = 66, Direita = 20 };

        case 'v':
          return new EspacamentoClass() { Esquerda = 10, Largura = 77, Direita = 9 };

        case 'w':
          return new EspacamentoClass() { Esquerda = 10, Largura = 102, Direita = 9 };

        case 'x':
          return new EspacamentoClass() { Esquerda = 11, Largura = 80, Direita = 11 };

        case 'y':
          return new EspacamentoClass() { Esquerda = 10, Largura = 85, Direita = 9 };

        case 'z':
          return new EspacamentoClass() { Esquerda = 12, Largura = 68, Direita = 12 };

        case '1':
          return new EspacamentoClass() { Esquerda = 12, Largura = 30, Direita = 14 };

        case '2':
          return new EspacamentoClass() { Esquerda = 11, Largura = 81, Direita = 11 };

        case '3':
          return new EspacamentoClass() { Esquerda = 5, Largura = 81, Direita = 10 };

        case '4':
          return new EspacamentoClass() { Esquerda = 4, Largura = 93, Direita = 14 };

        case '5':
          return new EspacamentoClass() { Esquerda = 11, Largura = 81, Direita = 11 };

        case '6':
          return new EspacamentoClass() { Esquerda = 10, Largura = 81, Direita = 10 };

        case '7':
          return new EspacamentoClass() { Esquerda = 6, Largura = 81, Direita = 10 };

        case '8':
          return new EspacamentoClass() { Esquerda = 10, Largura = 81, Direita = 10 };

        case '9':
          return new EspacamentoClass() { Esquerda = 10, Largura = 81, Direita = 10 };

        case '0':
          return new EspacamentoClass() { Esquerda = 10, Largura = 84, Direita = 10 };

        case '&':
          return new EspacamentoClass() { Esquerda = 10, Largura = 90, Direita = 10 };

        case '!':
          return new EspacamentoClass() { Esquerda = 14, Largura = 20, Direita = 14 };

        case '\"':
          return new EspacamentoClass() { Esquerda = 14, Largura = 57, Direita = 14 };

        case '#':
          return new EspacamentoClass() { Esquerda = 10, Largura = 88, Direita = 10 };

        case '$':
          return new EspacamentoClass() { Esquerda = 11, Largura = 81, Direita = 11 };

        case '¢':
          return new EspacamentoClass() { Esquerda = 10, Largura = 67, Direita = 8 };

        case '/':
          return new EspacamentoClass() { Esquerda = 0, Largura = 107, Direita = 0 };

        case '*':
          return new EspacamentoClass() { Esquerda = 8, Largura = 56, Direita = 8 };

        case '.':
          return new EspacamentoClass() { Esquerda = 4, Largura = 20, Direita = 4 };

        case ',':
          return new EspacamentoClass() { Esquerda = 4, Largura = 20, Direita = 4 };

        case ':':
          return new EspacamentoClass() { Esquerda = 4, Largura = 20, Direita = 4 };

        case '(':
          return new EspacamentoClass() { Esquerda = 10, Largura = 38, Direita = 4 };

        case ')':
          return new EspacamentoClass() { Esquerda = 4, Largura = 38, Direita = 10 };

        case '-':
          return new EspacamentoClass() { Esquerda = 3, Largura = 35, Direita = 3 };

        case '@':
          return new EspacamentoClass() { Esquerda = 10, Largura = 101, Direita = 10 };

        case '=':
          return new EspacamentoClass() { Esquerda = 3, Largura = 65, Direita = 3 };

        case '+':
          return new EspacamentoClass() { Esquerda = 3, Largura = 65, Direita = 3 };

        case '?':
          return new EspacamentoClass() { Esquerda = 7, Largura = 69, Direita = 7 };

        case ' ':
          return new EspacamentoClass() { Esquerda = 0, Largura = 75, Direita = 0 };

        default:
          throw new ApplicationException("Erro ao calcular o espaçamento das letras!");
      }
    }

    private EspacamentoClass Letra100D(char Letra)
    {
      switch (Letra)
      {
        case 'A':
        case 'Á':
        case 'Ã':
        case 'Â':
        case 'À':
          return new EspacamentoClass() { Esquerda = 3, Largura = 85, Direita = 3 };

        case 'B':
          return new EspacamentoClass() { Esquerda = 12, Largura = 68, Direita = 5 };

        case 'C':
        case 'Ç':
          return new EspacamentoClass() { Esquerda = 10, Largura = 68, Direita = 10 };

        case 'D':
          return new EspacamentoClass() { Esquerda = 12, Largura = 68, Direita = 10 };

        case 'E':
        case 'É':
        case 'Ê':
        case 'È':
          return new EspacamentoClass() { Esquerda = 12, Largura = 62, Direita = 5 };

        case 'F':
          return new EspacamentoClass() { Esquerda = 12, Largura = 62, Direita = 3 };

        case 'G':
          return new EspacamentoClass() { Esquerda = 10, Largura = 68, Direita = 10 };

        case 'H':
          return new EspacamentoClass() { Esquerda = 12, Largura = 68, Direita = 12 };

        case 'I':
        case 'Í':
        case 'Ì':
        case 'Î':
          return new EspacamentoClass() { Esquerda = 12, Largura = 16, Direita = 12 };

        case 'J':
          return new EspacamentoClass() { Esquerda = 3, Largura = 64, Direita = 12 };

        case 'K':
          return new EspacamentoClass() { Esquerda = 12, Largura = 70, Direita = 5 };

        case 'L':
          return new EspacamentoClass() { Esquerda = 12, Largura = 62, Direita = 3 };

        case 'M':
          return new EspacamentoClass() { Esquerda = 12, Largura = 78, Direita = 12 };

        case 'N':
          return new EspacamentoClass() { Esquerda = 12, Largura = 68, Direita = 12 };

        case 'O':
        case 'Ó':
        case 'Ò':
        case 'Õ':
        case 'Ô':
          return new EspacamentoClass() { Esquerda = 10, Largura = 71, Direita = 10 };

        case 'P':
          return new EspacamentoClass() { Esquerda = 12, Largura = 68, Direita = 4 };

        case 'Q':
          return new EspacamentoClass() { Esquerda = 10, Largura = 71, Direita = 10 };

        case 'R':
          return new EspacamentoClass() { Esquerda = 12, Largura = 68, Direita = 7 };

        case 'S':
          return new EspacamentoClass() { Esquerda = 5, Largura = 68, Direita = 11 };

        case 'T':
          return new EspacamentoClass() { Esquerda = 3, Largura = 62, Direita = 4 };

        case 'U':
        case 'Ú':
        case 'Ù':
        case 'Û':
          return new EspacamentoClass() { Esquerda = 12, Largura = 68, Direita = 14 };

        case 'V':
          return new EspacamentoClass() { Esquerda = 3, Largura = 76, Direita = 4 };

        case 'W':
          return new EspacamentoClass() { Esquerda = 3, Largura = 89, Direita = 4 };

        case 'X':
          return new EspacamentoClass() { Esquerda = 5, Largura = 68, Direita = 7 };

        case 'Y':
          return new EspacamentoClass() { Esquerda = 3, Largura = 86, Direita = 4 };

        case 'Z':
          return new EspacamentoClass() { Esquerda = 5, Largura = 68, Direita = 7 };

        case '1':
          return new EspacamentoClass() { Esquerda = 10, Largura = 25, Direita = 12 };

        case '2':
          return new EspacamentoClass() { Esquerda = 10, Largura = 68, Direita = 10 };

        case '3':
          return new EspacamentoClass() { Esquerda = 18, Largura = 68, Direita = 10 };

        case '4':
          return new EspacamentoClass() { Esquerda = 2, Largura = 75, Direita = 12 };

        case '5':
          return new EspacamentoClass() { Esquerda = 10, Largura = 68, Direita = 10 };

        case '6':
          return new EspacamentoClass() { Esquerda = 10, Largura = 68, Direita = 10 };

        case '7':
          return new EspacamentoClass() { Esquerda = 7, Largura = 68, Direita = 7 };

        case '8':
          return new EspacamentoClass() { Esquerda = 10, Largura = 68, Direita = 10 };

        case '9':
          return new EspacamentoClass() { Esquerda = 10, Largura = 68, Direita = 10 };

        case '0':
          return new EspacamentoClass() { Esquerda = 10, Largura = 71, Direita = 10 };

        case '&':
          return new EspacamentoClass() { Esquerda = 10, Largura = 89, Direita = 0 };

        case '!':
          return new EspacamentoClass() { Esquerda = 12, Largura = 16, Direita = 12 };

        case '\"':
          return new EspacamentoClass() { Esquerda = 4, Largura = 18, Direita = 4 };

        case '#':
          return new EspacamentoClass() { Esquerda = 6, Largura = 85, Direita = 6 };

        case '$':
          return new EspacamentoClass() { Esquerda = 5, Largura = 68, Direita = 5 };

        case '¢':
          return new EspacamentoClass() { Esquerda = 10, Largura = 61, Direita = 7 };

        case '/':
          return new EspacamentoClass() { Esquerda = 0, Largura = 103, Direita = 0 };

        case '*':
          return new EspacamentoClass() { Esquerda = 8, Largura = 54, Direita = 8 };

        case '.':
          return new EspacamentoClass() { Esquerda = 4, Largura = 18, Direita = 4 };

        case ',':
          return new EspacamentoClass() { Esquerda = 4, Largura = 18, Direita = 4 };

        case ':':
          return new EspacamentoClass() { Esquerda = 4, Largura = 18, Direita = 4 };

        case '(':
          return new EspacamentoClass() { Esquerda = 10, Largura = 33, Direita = 4 };

        case ')':
          return new EspacamentoClass() { Esquerda = 4, Largura = 33, Direita = 10 };

        case '-':
          return new EspacamentoClass() { Esquerda = 3, Largura = 35, Direita = 3 };

        case '@':
          return new EspacamentoClass() { Esquerda = 10, Largura = 100, Direita = 10 };

        case '=':
          return new EspacamentoClass() { Esquerda = 12, Largura = 48, Direita = 12 };

        case '+':
          return new EspacamentoClass() { Esquerda = 3, Largura = 67, Direita = 3 };

        case '?':
          return new EspacamentoClass() { Esquerda = 7, Largura = 65, Direita = 7 };

        case ' ':
          return new EspacamentoClass() { Esquerda = 0, Largura = 75, Direita = 0 };

        default:
          throw new ApplicationException("Erro ao calcular o espaçamento das letras!");
      }
    }
  }
}